﻿/*  
 *  IIS LogFile Analyser, Copyright (C) 2013. http://www.iis-analyser.com
 *  --
 *  This program is free software, provided "AS IS" WITHOUT ANY WARRANTY; without even the implied warranty of 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE
 * 
 *  File Author: Ian Quigley,    2013-02-23
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SQLite;

namespace DataStore
{
    [TableName("File")]
    public class FileRecord
    {
        [FieldDescription("Id", "Long Primary Key")]
        public long Id { get; private set; }
        [FieldDescription("SiteId", "Long Foreign Key to Site table")]
        public long SiteId { get; set; }
        [FieldDescription("FilePath", "string filepath for file")]
        public string FilePath { get; internal set; }
        [FieldDescription("Updated", "Datetime, when file was update")]
        public DateTime Updated { get; set; }
        [FieldDescription("FileDate", "Datetime, the date stored in the log file")]
        public DateTime FileDate { get; set; }
        [FieldDescription("LinesRead", "Long, Number of lines read")]
        public long LinesRead { get; set; }
        [FieldDescription("SizeBytes", "Long, file size when last read")]
        public long SizeBytes { get; set; }

        internal FileRecord()
        {
        }

        internal static void InitialiseTable()
        {
            using (var db = Database.Open())
            using (SQLiteCommand command = new SQLiteCommand( "CREATE TABLE if not exists File (Id Integer PRIMARY KEY AutoIncrement, SiteId integer, FilePath Text, Updated Datetime, FileDate DateTime, LinesRead Integer, SizeBytes integer)", db.Connection ))
            {
                db.Connection.Open();
                command.ExecuteNonQuery();
            }
        }

        public void Save()
        {
            using (var db = Database.Open())
            using (SQLiteCommand command = new SQLiteCommand( "INSERT OR REPLACE INTO File (" +
                (Id == 0 ? "" : "Id, ") +
                "SiteId, FilePath, Updated, FileDate, LinesRead, SizeBytes" +
                ") VALUES (" +
                (Id == 0 ? "" : "@id, ") +
                "@sid, @fp, @upd, @fd, @lr, @sz"+
                "); select last_insert_rowid();", db.Connection ))
            {
                if (Id != 0)
                    command.Parameters.AddWithValue( "@id", Id);

                command.Parameters.AddWithValue( "@sid", SiteId);
                command.Parameters.AddWithValue( "@fp", FilePath );
                command.Parameters.AddWithValue( "@upd", Updated);
                command.Parameters.AddWithValue( "@fd", FileDate);
                command.Parameters.AddWithValue( "@lr", LinesRead );
                command.Parameters.AddWithValue( "@sz", SizeBytes);

                db.Connection.Open();
                Id = (long)command.ExecuteScalar();
            }
        }

        internal static FileRecord FindOrCreate( SiteRecord site, string filePath )
        {
            using (var db = Database.Open())
            using (SQLiteCommand command = new SQLiteCommand( "SELECT Id, SiteId, FilePath, Updated, FileDate, LinesRead, SizeBytes FROM File WHERE FilePath like @p0;", db.Connection))
            {
                command.Parameters.AddWithValue( "@p0", filePath );

                db.Connection.Open();
                var reader = command.ExecuteReader();
                
                FileRecord file = new FileRecord();
                if (!reader.Read())
                {
                    file.SiteId = site.Id;
                    file.FilePath= filePath;
                    file.Updated = DateTime.UtcNow;
                    file.LinesRead = 0;
                    file.SizeBytes = 0;
                    file.Save();
                }
                else
                {
                    file = FromReader( reader );
                }

                return file;
            }
        }

        internal static IEnumerable<FileRecord> ForSite(long siteId)
        {
            using (var db = Database.Open())
            using (SQLiteCommand command = new SQLiteCommand( "SELECT Id, SiteId, FilePath, Updated, FileDate, LinesRead, SizeBytes FROM File WHERE SiteId = @p0;", db.Connection ))
            {
                command.Parameters.AddWithValue( "@p0", siteId );

                db.Connection.Open();
                var reader = command.ExecuteReader();
                while (reader.Read())
                    yield return FromReader( reader );
            }            
        }

        internal static FileRecord FromReader(SQLiteDataReader reader)
        {
            return new FileRecord()
            {
                Id = (long)reader["Id"],
                SiteId = (long)reader["SiteId"],
                FilePath = (string)reader["FilePath"],
                Updated = (DateTime)reader["Updated"],
                FileDate = (DateTime)reader["FileDate"],
                LinesRead = (long)reader["LinesRead"],
                SizeBytes = (long)reader["SizeBytes"]
            };
        }
    }
}
